using System.Collections.Generic;
using Microsoft.Xna.Framework;

using HMEngine.HMComponents;
using HMEngine.HMEffects;
using Microsoft.Xna.Framework.Graphics;

namespace HMEngine.HMObjects {
    public class HMObjectManager : DrawableGameComponent {
        private static readonly Dictionary<string, HMObject> masterList = new Dictionary<string, HMObject>();
        private static readonly Dictionary<string, HMObject> renderable = new Dictionary<string, HMObject>();
        private static readonly Dictionary<string, HMObject> loadable = new Dictionary<string, HMObject>();

        public HMObjectManager(Game game) : base(game) { }

        public static void AddObject(string name, HMObject newObject) {
            masterList.Add(name, newObject);
            if (newObject is IHMRenderable) renderable.Add(name, newObject);
            if (newObject is IHMLoadable) loadable.Add(name, newObject);
        }

        public static HMObject GetObject(string name) {
            if (masterList.ContainsKey(name)) return masterList[name];

            return null;
        }

        protected override void LoadContent() {
            foreach (IHMLoadable obj in loadable.Values) {
                obj.LoadContent(GraphicsDevice, Game.Content);
            }

            base.LoadContent();
        }

        public override void Draw(GameTime gameTime) {
            foreach (IHMRenderable obj in renderable.Values) {
                GraphicsDevice.VertexDeclaration = obj.VertexDeclaration;

                HMEffectManager.SetActiveShader(obj.Shader);
                if (obj is IHMHasMaterial) (obj as IHMHasMaterial).SetMaterialProperties();
                HMEffectManager.ActiveShader.SetParameters(obj as HMObject);

                HMEffectManager.ActiveShader.Effect.Begin();
                foreach (EffectPass pass in HMEffectManager.ActiveShader.Effect.CurrentTechnique.Passes) {
                    pass.Begin();
                    obj.Render(GraphicsDevice);
                    pass.End();
                }
                HMEffectManager.ActiveShader.Effect.End();
            }

            base.Draw(gameTime);
        }
    }
}